package com.fegin.util;


import com.alibaba.fastjson.JSONObject;
import com.util.Respons.ResponseCode;
import com.util.Respons.ResponseMsg;
import com.util.Respons.ResponseUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/**
 * @author 张子艺
 * @packge com.util
 * @data 2019-01-22 18:09
 * @project CurrenCy-Cloud
 */
public class GenerateWord {

    public static void main(String[] args) throws Exception {
        GenerateWord generateWord = new GenerateWord();
        generateWord.main("http://localhost/app/v2/api-docs");


    }

    public void main(String swaggerURL) throws Exception {
        String title = "";
        String json = httpGet(swaggerURL);
        System.err.println(json);
        Map jsonMap = JSONObject.parseObject(json, Map.class);
        Map<String, Object> dataMap = new HashMap<String, Object>();


        //接口文档信息 Info
        Map infoMap = JSONObject.parseObject(jsonMap.get("info").toString(), Map.class);
        title = infoMap.get("title") + "";
        //接口类 数组
        System.err.println(jsonMap.get("paths"));

        Map pathsMap = JSONObject.parseObject(jsonMap.get("paths").toString(), Map.class);
        //排序
        List list = arrSort(new ArrayList(pathsMap.keySet()));

        List listData = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            Map map = new HashMap();
            map.put("classPath", list.get(i));
            //获取请求方式
            List requestWay = new ArrayList(JSONObject.parseObject(pathsMap.get(list.get(i)).toString(), Map.class).keySet());
            //获取请求方式下一层
            Map wayDownMap = JSONObject.parseObject(JSONObject.parseObject(pathsMap.get(list.get(i)).toString(), Map.class).get(requestWay.get(0)).toString(), Map.class);

            //获取接口参数
            List params = JSONObject.parseObject(wayDownMap.get("parameters").toString(), ArrayList.class);
            //当前接口的参数集合
            List currParams = new ArrayList();
            for (int j = 0; j < params.size(); j++) {
                Map paramMap = JSONObject.parseObject(params.get(j).toString(), Map.class);
                System.err.println(paramMap);
                //当前接口的参数 Map
                Map currParamMa = new HashMap();
                if (paramMap.get("schema") != null) {
                    //如果是实体类参数
                    Class<?> testTypeForName = Class.forName("com.fegin.bean." + toUpperCaseFirstOne(paramMap.get("name") + ""));
                    currParams = Reflex.parseMethod(testTypeForName, paramMap);

                } else {
                    //本个参数的属性
                    currParamMa.put("paramWay", paramMap.get("in"));
                    currParamMa.put("name", paramMap.get("name"));
                    currParamMa.put("paramDoc", paramMap.get("description"));
                    currParamMa.put("type", paramMap.get("type"));
                    currParamMa.put("required", paramMap.get("required"));
                    currParams.add(currParamMa);

                }

            }

            //接口返回值
            Map responesMap = JSONObject.parseObject(wayDownMap.get("responses").toString(), Map.class);
            String bean = JSONObject.parseObject(responesMap.get("200") + "", Map.class).get("description").toString();
            //如果是实体类参数
            try {
                Class<?> testTypeForName = Class.forName("com.fegin.bean." + bean);
                responesMap = parseMethod(testTypeForName);
            } catch (ClassNotFoundException e) {
                if (bean.equals("OK")) {
                    responesMap = ResponseUtil.getResultMap(ResponseCode.NORMAL, "", ResponseMsg.OPERATION_SUCCESS);
                } else {
                    responesMap = ResponseUtil.getResultMap(ResponseCode.NORMAL, bean, ResponseMsg.OPERATION_SUCCESS);
                }
            }
            JSONTool jsonTool = new JSONTool();
            //接口注释
            map.put("classPathDoc", wayDownMap.get("summary").toString().replace("</br>", " "));
            map.put("requestWay", requestWay.get(0));
            //参数
            map.put("params", currParams);
            map.put("paramsList", currParams);
            map.put("respones", jsonTool.stringToJSON(JSONObject.toJSONString(responesMap)));
            listData.add(map);
        }


        for (int i = 0; i < list.size(); i++) {
            System.err.println(list.get(i));
        }

        //接口详细信息
        //  dataMap.put("paths", );
        dataMap.put("infoMap", infoMap);
        dataMap.put("host", jsonMap.get("host"));
        dataMap.put("basePath", jsonMap.get("basePath"));
        dataMap.put("listData", listData);


        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setDirectoryForTemplateLoading(new File(ResourceUtils.getURL("classpath:").getPath()));

// 输出文档路径及名称
        File outFile = new File("F:\\" + title + ".doc");
//以utf-8的编码读取ftl文件
        Template t = configuration.getTemplate("Templet.ftl", "utf-8");

        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);

        t.process(dataMap, out);

        out.close();
    }

    //排序请求地址
    public static List arrSort(List list) {
        List list1 = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            list1.add(list.get(i).toString().substring(1));
        }
        Collections.sort(list1);

        for (int i = 0; i < list1.size(); i++) {
            list1.set(i, "/" + list1.get(i));
        }
        System.err.println(list1);
        return list1;

    }


    /**
     * Http Get 请求
     */
    private static String httpGet(String urlString) {
        String result = "";
        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = rd.readLine()) != null) {
                result += line;
            }
            rd.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取属性名数组
     */
    private static String[] getFiledName(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
//            System.out.println(fields[i].getType());
            fieldNames[i] = fields[i].getName();
        }
        return fieldNames;
    }

    //首字母转大写
    public static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }


    private static Map parseMethod(Class clazz) {
        Map map = new HashMap();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ApiModelProperty methodAnnotation = field.getAnnotation(ApiModelProperty.class);

            if (methodAnnotation != null) {
                map.put(field.getName(), methodAnnotation.value() + "|类型" + field.getType().getSimpleName());
            }
        }
        return ResponseUtil.getSuccessMap(map);
    }
}
